package com.nexgo.payment.trans.salevoid;

import android.support.annotation.NonNull;
import android.text.TextUtils;

import com.nexgo.payment.aop.annotation.TransCondition;
import com.nexgo.payment.trans.TransFlow;
import com.nexgo.data.entity.RecvData;
import com.nexgo.oaf.apiv3.emv.EmvAlgorithmTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvChannelTypeEnum;
import com.nexgo.oaf.apiv3.emv.EmvProcessResultEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransDataEntity;
import com.nexgo.oaf.apiv3.emv.EmvTransFlowEnum;
import com.nexgo.payment.App;
import com.nexgo.payment.R;
import com.nexgo.payment.action.ActionResult;
import com.nexgo.payment.action.ActionStep;
import com.nexgo.payment.constrant.CardMode;
import com.nexgo.payment.constrant.PreferencesConstants;
import com.nexgo.payment.constrant.SysConstant;
import com.nexgo.payment.constrant.TransType;
import com.nexgo.payment.databases.DataSource;
import com.nexgo.payment.databases.TransRecord;
import com.nexgo.payment.entity.TransData;
import com.nexgo.payment.trans.AbsTransPresenter;
import com.nexgo.payment.util.TransUtils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * 撤销业务操作
 *
 * @author 谭忠扬-YuriTam
 * @time 2017年8月28日
 */
@TransCondition
@TransFlow(checkFreePinBySetting = true)
public class SaleVoidPresenter extends AbsTransPresenter implements SaleVoidContract.Presenter {
    private Logger mLog = LoggerFactory.getLogger(SaleVoidPresenter.class.getSimpleName());

    private SaleVoidContract.View mView;
    private String mTraceNum;
    private String mOrgCardNo = "";

    public SaleVoidPresenter(@NonNull SaleVoidContract.View view, @NonNull DataSource repository, String traceNum) {
        super(view, repository);
        mView = checkNotNull(view);
        mTraceNum = traceNum;
        mView.setPresenter(this);
    }

    @Override
    protected TransData getTransData() {
        TransData transData = new TransData();
        transData.setTransType(TransType.VOID);
        return transData;
    }

    @Override
    protected EmvTransDataEntity getEmvTransData(EmvChannelTypeEnum channelType) {
        EmvTransDataEntity emvTransData = new EmvTransDataEntity();
        emvTransData.setChannelType(channelType);
        emvTransData.setB9C((byte) 0x20);
        emvTransData.setTransAmt(mTransData.getAmount());
        emvTransData.setTermId(mRepository.getParamValue(PreferencesConstants.TERMINAL_ID));
        emvTransData.setMerId(mRepository.getParamValue(PreferencesConstants.MERCHANT_ID));
        emvTransData.setMerName(mRepository.getParamValue(PreferencesConstants.MERCHANT_NAME));
        emvTransData.setTransDate(new SimpleDateFormat("yyMMdd", SysConstant.LOCALE).format(new Date()));
        emvTransData.setTransTime(new SimpleDateFormat("hhmmss", SysConstant.LOCALE).format(new Date()));
        emvTransData.setTraceNo(mRepository.getParamValue(PreferencesConstants.TRACE_NUMBER));
        emvTransData.setAlgType("1".equals(mRepository.getParamValue(PreferencesConstants.EMV_SUPPORT_SM2)) ?
                EmvAlgorithmTypeEnum.SM2 : EmvAlgorithmTypeEnum.RSA);
        if (channelType == EmvChannelTypeEnum.FROM_PICC) {
            emvTransData.setProcType(EmvTransFlowEnum.QPASS);
            emvTransData.setIsForceOnline(true);
        } else {
            emvTransData.setProcType(EmvTransFlowEnum.SIMPLE);
            emvTransData.setChannelType(EmvChannelTypeEnum.FROM_ICC);
        }
        return emvTransData;
    }

    @Override
    protected void onFirstAction() {
        postMainThread(() -> mView.showInputAdminPassword());
    }

    @Override
    public void importActionResult(ActionResult actionResult) {
        Object data = actionResult.getData();
        ActionStep step = (ActionStep) actionResult.getAction().getActionStep();
        int ret = actionResult.getRet();
        mLog.debug("curr action step {} ret {}", step, actionResult.getRet());
        //成功处理进行处理，否则让父类处理
        if (ret == ActionResult.SUCC) {
            switch (step) {
                case INPUT_ADMIN_PSW:
                    inputAdminPasswordNext(data);
                    return;
                case INPUT_TRACE_NUM:
                    inputTraceNumNext(data);
                    return;
                case CONFIRM_TRANS_DETAIL:
                    confirmTransDetailNext(data);
                    return;
                default:
                    break;
            }
        }
        super.importActionResult(actionResult);
    }

    /**
     * 输入主管密码后下一步
     *
     * @param data
     */
    protected void inputAdminPasswordNext(Object data) {
        if (TextUtils.isEmpty(mTraceNum)) {
            postMainThread(() -> mView.showInputTraceNum());
            return;
        }
        confirmTransDetailNext(null);
    }

    /**
     * 输入凭证号后下一步
     *
     * @param data
     */
    protected void inputTraceNumNext(Object data) {
        String traceNum = (String) data;
        if (TextUtils.isEmpty(traceNum) || !TextUtils.isDigitsOnly(traceNum)) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.err_trace_num)));
            return;
        }
        TransRecord transRecord = mRepository.queryTransRecord(traceNum);
        if (transRecord == null) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.trace_num_not_exsit)));
            return;
        }
        if (TransType.SALE.ordinal() != transRecord.getTransType() || !transRecord.getIsSuccess()) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.err_trans_type_for_void)));
            return;
        }
        if (transRecord.getIsVoid()) {
            postMainThread(() -> mView.showError(App.sContext.getString(R.string.err_trans_is_void)));
            return;
        }
        mTransData.setOrgTraceNum(traceNum);
        postMainThread(() -> mView.showConfirmTransDetail(traceNum));
    }

    /**
     * 确认交易详情后下一步
     *
     * @param data
     */
    protected void confirmTransDetailNext(Object data) {
        TransRecord transRecord = null;
        if (!TextUtils.isEmpty(mTraceNum)) {
            transRecord = mRepository.queryTransRecord(mTraceNum);
        } else {
            transRecord = (TransRecord) data;
        }
        mTransData.setAmount(transRecord.getAmount());
        mOrgCardNo = transRecord.getPan();
        mTransData.setPan(transRecord.getPan());
        mTransData.setOrgTraceNum(transRecord.getTraceNum());
        mTransData.setOrgAuthCode(transRecord.getAuthCode());
        mTransData.setOrgRefNum(transRecord.getRefNum());
        mTransData.setOrgBatchNum(transRecord.getBatchNum());
        // 判断撤销交易是否需要刷卡
        if ("1".equals(mRepository.getParamValue(PreferencesConstants.TRANS_VOID_SWIPE_CARD))) {
            postMainThread(() -> mView.showReadCard(mTransData));
            return;
        }
        mTransData.setCardMode(CardMode.MANUAL);
        if (TransUtils.isTransNeedPin(mTransData.getTransType(), mRepository)) {
            postMainThread(() -> mView.showInputPin(mTransData, true, 0));
            return;
        }
        mTransData.setEntryMode(TransUtils.getEntryMode(mTransData.getCardMode(), null, mTransData.getPin() != null , mTransData.isFallback()));
        postMainThread(() -> mView.showOnlineProc(mTransData, null));
    }

    /**
     * 检测卡号是否一致
     *
     * @param cardNo 卡号
     * @return
     */
    @Override
    public boolean checkOrigCardNo(String cardNo) {
        return mOrgCardNo.equals(cardNo);
    }

    @Override
    protected void onTransSuccess(RecvData recvData, EmvProcessResultEntity emvResult) {
        postMainThread(() -> mView.quitTrans());
    }

}
